home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / smlltalk / smtk_11.zoo / mstsym.c < prev    next >
C/C++ Source or Header  |  1990-05-26  |  22KB  |  879 lines

  1. /***********************************************************************
  2.  *
  3.  *    Symbol Table module.
  4.  *
  5.  ***********************************************************************/
  6.  
  7. /***********************************************************************
  8.  *
  9.  * Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
  10.  * Written by Steve Byrne.
  11.  *
  12.  * This file is part of GNU Smalltalk.
  13.  *
  14.  * GNU Smalltalk is free software; you can redistribute it and/or modify it
  15.  * under the terms of the GNU General Public License as published by the Free
  16.  * Software Foundation; either version 1, or (at your option) any later 
  17.  * version.
  18.  * 
  19.  * GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
  20.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
  21.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  22.  * more details.
  23.  * 
  24.  * You should have received a copy of the GNU General Public License along with
  25.  * GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
  26.  * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
  27.  *
  28.  ***********************************************************************/
  29.  
  30.  
  31. /*
  32.  *    Change Log
  33.  * ============================================================================
  34.  * Author      Date       Change 
  35.  * sbyrne    16 May 90      Changed usages of "entry" to "ent" to prevent
  36.  *              collisions with C compilers which have this
  37.  *              identifier as a reserved word.
  38.  *
  39.  * sbyrne    21 Apr 90      Addded byteArraySymbol.
  40.  *
  41.  * sbyrne    13 Jan 90      Added thisContextSymbol.
  42.  *
  43.  * sbyrne    19 Dec 89      Rebuilt symbol table.  Used to use the main OOP table
  44.  *              as a symbol table, due to issues involving initial
  45.  *              bootstrapping of the system.  Now using open hash
  46.  *              table built of arrays and linked lists, so that no
  47.  *              special precautions need be taken by the GC system or
  48.  *              the image save/restore facility.
  49.  *
  50.  * sbyrne    25 Jul 89      Changed undeclareName to take a parameter that
  51.  *              controls whether the frame index is decremented or
  52.  *              not.  It appears that each block gets its own,
  53.  *              non-shared temporaries/arguments, so that if the
  54.  *              block is used in a process, other blocks won't have
  55.  *              strange things happening to their arguments.
  56.  *
  57.  * sbyrne     5 Jan 89      Created.
  58.  *
  59.  */
  60.  
  61. #include "mst.h"
  62. #include "mstsym.h"
  63. #include "mstoop.h"
  64. #include "mstcomp.h"
  65. #include "mstdict.h"
  66. #include "msttree.h"
  67. #include <stdio.h>
  68. #include <ctype.h>
  69. #ifdef HAS_ALLOCA_H
  70. #include <alloca.h>
  71. #endif
  72.  
  73. /* if defined, use the hash algorithm given in the dragon book (see usage for
  74.    better reference. */
  75. #define dragon_book
  76.  
  77. #define    max(x, y) \
  78.   ( ((x) > (y)) ? (x) : (y) )
  79.  
  80. #define isSymbol(oop) \
  81.    ( !isNil(oop) && (oopClass(oop) ==  symbolClass) )
  82.  
  83. typedef struct {
  84.   OBJ_HEADER;
  85.   OOP        nextLink;
  86.   OOP        symbol;
  87. } *SymLink;
  88.  
  89. OOP            andColonSymbol, atColonPutColonSymbol, atColonSymbol,
  90.             atEndSymbol, bitAndColonSymbol, bitOrColonSymbol,
  91.             bitShiftColonSymbol, blockCopyColonSymbol, classSymbol,
  92.             divideSymbol, doColonSymbol, equalSymbol,
  93.             greaterEqualSymbol, greaterThanSymbol,
  94.             ifFalseColonIfTrueColonSymbol, ifFalseColonSymbol,
  95.             ifTrueColonIfFalseColonSymbol, ifTrueColonSymbol,
  96.             integerDivideSymbol, lessEqualSymbol, lessThanSymbol,
  97.             minusSymbol, newColonSymbol, newSymbol,
  98.             nextPutColonSymbol, nextSymbol, notEqualSymbol,
  99.             notSameObjectSymbol, orColonSymbol, plusSymbol,
  100.             remainderSymbol, sameObjectSymbol, sizeSymbol,
  101.             thisContextSymbol,
  102.             timesSymbol, valueColonSymbol,
  103.             valueColonValueColonSymbol,
  104.             valueColonValueColonValueColonSymbol,
  105.              valueWithArgumentsColonSymbol,
  106.             valueSymbol,
  107.             whileFalseColonSymbol, whileTrueColonSymbol, orSymbol,
  108.             andSymbol, superSymbol, nilSymbol, trueSymbol,
  109.             falseSymbol, selfSymbol,
  110.             doesNotUnderstandColonSymbol, unknownSymbol,
  111.             charSymbol, stringSymbol, stringOutSymbol, 
  112.             symbolSymbol, intSymbol, longSymbol, doubleSymbol,
  113.             voidSymbol, variadicSymbol, cObjectSymbol, 
  114.             smalltalkSymbol, symbolTable, byteArraySymbol;
  115.  
  116. #ifdef symbol_table_profiling
  117. int            adds = 0, reused = 0, reprobes = 0,
  118.             hitsOn[OOP_TABLE_SIZE];
  119. #endif /* symbol_table_profiling */
  120.  
  121. void             printString();
  122.  
  123. static SymbolEntry    allocSymbolEntry();
  124. static Symbol        makeNewSymbol();
  125. static Boolean        isSameString(), isWhiteSpace();
  126. unsigned long        hashString();
  127. static void        declareName(), undeclareName(), parseVariableName();
  128. static OOP        scanName(), internCountedString();
  129. static int        instanceVariableIndex(), localVarIndex();
  130.  
  131. typedef struct SymbolListStruct *SymbolList;
  132.  
  133. struct SymbolListStruct {
  134.   OOP        symbol;
  135.   int        index;
  136.   SymbolList    prevSymbol;
  137. };
  138.   
  139. static SymbolList    symbolList;
  140. static int        methodArguments, frameIndex, maxFrameIndex;
  141.  
  142.  
  143. int getArgCount()
  144. {
  145.   return (methodArguments);
  146. }
  147.  
  148. int getTempCount()
  149. {
  150.   return (maxFrameIndex - methodArguments);
  151. }
  152.  
  153. void initArgCount()
  154. {
  155.   methodArguments = 0;
  156. }
  157.  
  158. void initTempCount()
  159. {
  160. }
  161.  
  162. void declareArguments(args)
  163. TreeNode args;
  164. {
  165.   symbolList = nil;
  166.   frameIndex = 0;
  167.   maxFrameIndex = 0;
  168.  
  169.   if (args->nodeType == unaryExprType) {
  170.     return;
  171.   } else if (args->nodeType == binaryExprType) {
  172.     declareName(args->vExpr.expression->vList.name);
  173.     methodArguments++;
  174.   } else {
  175.     for(args = args->vExpr.expression; args != nil; args = args->vList.next) {
  176.       declareName(args->vList.value->vList.name);
  177.       methodArguments++;
  178.     }
  179.   }
  180. }
  181.   
  182. void declareTemporaries(temps)
  183. TreeNode temps;
  184. {
  185.   for( ; temps != nil; temps = temps->vList.next) {
  186.     declareName(temps->vList.name);
  187.   }
  188. }
  189.  
  190. void declareBlockArguments(args)
  191. TreeNode args;
  192. {
  193.   for( ; args != nil; args = args->vList.next) {
  194.     declareName(args->vList.name);
  195.   }
  196. }
  197.  
  198. static void declareName(name)
  199. char    *name;
  200. {
  201.   SymbolList    newList;
  202.  
  203.   newList = (SymbolList)malloc(sizeof(struct SymbolListStruct));
  204.   newList->symbol = internString(name);
  205.   newList->index = frameIndex++;
  206.   maxFrameIndex = max(maxFrameIndex, frameIndex);
  207.   newList->prevSymbol = symbolList;
  208.   symbolList = newList;
  209. }
  210.  
  211. void undeclareArguments(args)
  212. TreeNode args;
  213. {
  214.   if (args == nil) {
  215.     return;
  216.   }
  217.  
  218.   if (args->nodeType == unaryExprType) {
  219.     return;
  220.   } else if (args->nodeType == binaryExprType) {
  221.     undeclareName(true);
  222.   } else {
  223.     for(args = args->vExpr.expression; args != nil; args = args->vList.next) {
  224.       undeclareName(true);
  225.     }
  226.   }
  227. }
  228.  
  229. void undeclareTemporaries(temps)
  230. TreeNode temps;
  231. {
  232.   for( ; temps != nil; temps = temps->vList.next) {
  233.     undeclareName(true);
  234.   }
  235. }
  236.  
  237. void undeclareBlockArguments(args)
  238. TreeNode args;
  239. {
  240.   if (args == nil) {
  241.     return;
  242.   }
  243.  
  244.   for( ; args != nil; args = args->vList.next) {
  245.     undeclareName(false);
  246.   }
  247. }
  248.  
  249. static void undeclareName(decrFrameIndex)
  250. Boolean decrFrameIndex;
  251. {
  252.   SymbolList    oldList;
  253.  
  254.   oldList = symbolList;
  255.   symbolList = symbolList->prevSymbol;
  256.   free(oldList);
  257.   if (decrFrameIndex) {
  258.     frameIndex--;
  259.   }
  260. }
  261.  
  262. OOP findClassVariable(varName)
  263. OOP    varName;
  264. {
  265.   OOP        classOOP, assocOOP, classVariableOOP;
  266.  
  267.   if (oopClass(thisClass) == behaviorClass
  268.       || oopClass(thisClass) == classDescriptionClass) {
  269.     /* classDescriptions and above don't have class or pool variables */
  270.     /* ### this isn't quite the right test; we probably should be testing
  271.        for if we have a classClass or some derivative of that */
  272.     return (nilOOP);
  273.   }
  274.  
  275.   for (classOOP = thisClass; !isNil(classOOP);
  276.        classOOP = superClass(classOOP)) {
  277.     if (oopClass(classOOP) == metaclassClass) {
  278.       /* pretend that metaclasses have the class variables and shared
  279.      pools that their instance classes do */
  280.       classVariableOOP = metaclassInstance(classOOP);
  281.     } else {
  282.       classVariableOOP = classOOP;
  283.     }
  284.     assocOOP =
  285.       dictionaryAssociationAt(classVariableDictionary(classVariableOOP),
  286.                   varName);
  287.     if (!isNil(assocOOP)) {
  288.       return (assocOOP);
  289.     }
  290.  
  291.     assocOOP = findSharedPoolVariable(classVariableOOP, varName);
  292.     if (!isNil(assocOOP)) {
  293.       return (assocOOP);
  294.     }
  295.   }
  296.  
  297.   return (nilOOP);
  298. }
  299.  
  300.  
  301. SymbolEntry findVariable(varName)
  302. char    *varName;
  303. {
  304.   OOP        varAssoc, symbol;
  305.   int        index;
  306.  
  307.   symbol = internString(varName);
  308.   index = localVarIndex(symbol);
  309.   if (index >= 0) {
  310.     return (allocSymbolEntry(tempora